/*
 * Ext GWT - Ext for GWT
 * Copyright(c) 2007-2009, Ext JS, LLC.
 * licensing@extjs.com
 * 
 * http://extjs.com/license
 */
package com.myBlast.client;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelFactory;
import com.extjs.gxt.ui.client.data.BeanModelLookup;
import com.extjs.gxt.ui.client.data.ModelComparer;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.IconButtonEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MenuEvent;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.store.StoreEvent;
import com.extjs.gxt.ui.client.store.StoreListener;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.MessageBox.MessageBoxType;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ToolButton;
import com.extjs.gxt.ui.client.widget.custom.Portal;
import com.extjs.gxt.ui.client.widget.custom.Portlet;
import com.extjs.gxt.ui.client.widget.form.CheckBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.FileUploadField;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.StoreFilterField;
import com.extjs.gxt.ui.client.widget.form.TextArea;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.AccordionLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.HBoxLayout;
import com.extjs.gxt.ui.client.widget.layout.HBoxLayout.HBoxLayoutAlign;
import com.extjs.gxt.ui.client.widget.menu.CheckMenuItem;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuBar;
import com.extjs.gxt.ui.client.widget.menu.MenuBarItem;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.XMLParser;
import com.myBlast.client.WidgetUtilities.Tracker;
import com.myBlast.client.icons.ExampleIcons;
import com.myBlast.client.models.FormModel;
import com.myBlast.client.models.NonLeafTaxonomyModel;
import com.myBlast.data.BlastResult;

/**
 * @author Parit Bansal
 */
public class MyPortal extends LayoutContainer implements Listener<ButtonEvent> {

	private static ComboBox<FormModel> qType = null;
	private static ComboBox<FormModel> gType = null;
	private static ComboBox<FormModel> blastPrg = null;
	private static ComboBox<FormModel> expectancyBox = null;
	private static ComboBox<FormModel> filterBox = null;
	private static ComboBox<FormModel> blastDatabase = null;
	private static CheckBox megaBlastCheck = null;
	private static CheckBox newProjectCheck = null;
	private static TextArea qArea = null;
	private static TreePanel<ModelData> tree = null;
	private static FormPanel formPanel = null;
	private static Button fetchButton = null;
	private static ContentPanel west = null;
	private final static WidgetUtilities utilities = new WidgetUtilities();

	public static Portal portal = null;
	public static TextField<String> txtField = null;
	public static boolean projectUnsaved = true;
	public static HashMap<String,BlastGrid> map = new HashMap<String, BlastGrid>();

	@Override
	protected void onRender(Element parent, int index) {
		super.onRender(parent, index);
		setLayout(new BorderLayout());

		Menu menu = new Menu();  
		MenuItem item1 = new MenuItem("New Project");
		item1.addListener(Events.Select, new SelectionListener<MenuEvent>() {
			@Override
			public void componentSelected(MenuEvent ce) {
				Window.Location.reload();
			}
		});

		menu.add(item1);
		MenuItem item2 = new MenuItem("Load Project");
		item2.addListener(Events.Select, new SelectionListener<MenuEvent>() {
			@Override
			public void componentSelected(MenuEvent ce) {
				newProjectCheck.setValue(false);
				preparePopUpPanel();
			}
		});

		menu.add(item1);
		menu.add(item2);

		MenuBar north = new MenuBar();  
		north.setBorders(true);  
		north.setStyleAttribute("borderTop", "none");
		MenuBarItem fileBar = new MenuBarItem("File", menu);
		fileBar.setWidth(String.valueOf(MyBlast.clientWidth/20));
		fileBar.setStyleName("topMenu");
		north.add(fileBar);
		menu = new Menu();
		fileBar = new MenuBarItem("Help", menu);
		fileBar.setStyleName("topMenu");
		MenuItem helpItem = new MenuItem("About Apex");
		helpItem.addListener(Events.Select, new SelectionListener<MenuEvent>() {
			@Override
			public void componentSelected(MenuEvent ce) {
				String msg = "(c) Copyright BioProcess Laboratory 2009, 2010.  All rights reserved.\n";
				MessageBox box = new MessageBox();
				box.setTitle("About Apex");
				box.setMessage(msg);
				box.setClosable(true);
				box.setIcon("dbsse");
				box.show();

			}
		});
		menu.add(helpItem);
		north.add(fileBar);

		BorderLayoutData northData = new BorderLayoutData(LayoutRegion.NORTH,25);

		west = new ContentPanel();
		west.setBodyBorder(false);
		west.setHeading("Query Panel");
		west.setLayout(new AccordionLayout());
		formPanel = makeForm(); 
		west.add(formPanel);
		west.setHeight(MyBlast.clientHeight - 100);

		BorderLayoutData westData = new BorderLayoutData(LayoutRegion.WEST, 350, 100, 500);
		westData.setMargins(new Margins(0, 0, 0, 0));
		westData.setCollapsible(true);

		portal = new Portal(3);
		portal.setBorders(true);
		portal.setStyleAttribute("backgroundColor", "white");
		portal.setColumnWidth(0, .33);
		portal.setColumnWidth(1, .67);
		portal.setAdjustForScroll(true);

		portal.add(makeTree(), 0);

		BorderLayoutData centerData = new BorderLayoutData(LayoutRegion.CENTER);
		centerData.setMargins(new Margins(0));

		add(north, northData);
		add(west, westData);
		add(portal, centerData);
	}
	/**
	 * This method populates a treepanel and returns it
	 * with organism data.
	 * @return A tree panel
	 */
	@SuppressWarnings("unchecked")
	private Portlet makeTree()
	{
		Portlet portlet = new Portlet();
		portlet.setLayout(new FitLayout());
		portlet.setHeight(MyBlast.clientHeight - 115);
		portlet.setHeading("Taxonomy Tree");
		portlet.setScrollMode(Scroll.AUTOY);

		NonLeafTaxonomyModel model = StaticData.getTaxTree();  
		TreeStore<ModelData> treeStore = new TreeStore<ModelData>();
		tree = new TreePanel<ModelData>(treeStore);  
		tree.setDisplayProperty("name");  
		tree.setCheckable(true);  
		tree.setAutoLoad(true);
		tree.setCheckStyle(TreePanel.CheckCascade.CHILDREN);
		treeStore.add(model.getChildren(), true); 
		treeStore.setModelComparer(new ModelComparer(){

			@Override
			public boolean equals(ModelData m1, ModelData m2) {
				String gid = m1.get("gid");
				String gid2 = m2.get("gid");
				if (gid != null && gid2 != null && gid.equals(gid2)) return true;
				return false;
			}
		});
		final StoreFilterField<ModelData> filter = createStoreFilterForTree();
		portlet.setTopComponent(createToolBarForTree(filter));
		portlet.add(tree);
		return portlet;
	}

	private ToolBar createToolBarForTree(StoreFilterField<ModelData> filter)
	{
		Menu scrollMenu = new Menu();
		SelectionListener<MenuEvent> listener = new SelectionListener<MenuEvent>() {
			@SuppressWarnings("unchecked")
			@Override
			public void componentSelected(MenuEvent ce) {
				Menu menu = (Menu)ce.getSource();
				Iterator<Component> iterator = menu.iterator();
				while(iterator.hasNext())
				{
					CheckMenuItem checkMenuItem = (CheckMenuItem) iterator.next();
					if (checkMenuItem.isChecked())
					{
						ToolBar toolbar = (ToolBar)menu.getParent().getParent();
						StoreFilterField<ModelData> filter = (StoreFilterField<ModelData>)toolbar.getItem(2);
						filter.setProperty(checkMenuItem.getTitle());
						break;
					}
				}
			}
		};

		scrollMenu.setMaxHeight(200);
		CheckMenuItem menuItem = new CheckMenuItem("By Name"); 
		menuItem.setChecked(true);
		menuItem.setTitle("name");
		filter.setProperty("name");
		menuItem.setGroup("props");
		menuItem.addSelectionListener(listener);
		scrollMenu.add(menuItem);
		menuItem = new CheckMenuItem("By Taxid");
		menuItem.setTitle("gid");
		menuItem.setChecked(false);
		menuItem.setGroup("props");
		menuItem.addSelectionListener(listener);
		scrollMenu.add(menuItem);
		Button scrollerButton = new Button("Property to search by"); 
		scrollerButton.setMenu(scrollMenu);

		ToolBar toolBar = new ToolBar();  
		toolBar.setBorders(true);  
		LabelToolItem labelToolItem = new LabelToolItem("Filter:");
		//		item.setWidth(30);
		toolBar.add(labelToolItem);  
		toolBar.add(filter);  
		toolBar.add(new SeparatorToolItem());
		toolBar.add(scrollerButton);
		toolBar.add(new SeparatorToolItem());
		return toolBar;

	}

	private StoreFilterField<ModelData> createStoreFilterForTree() {
		StoreFilterField<ModelData> filter = new StoreFilterField<ModelData>() {  

			@Override  
			protected boolean doSelect(Store<ModelData> store, ModelData parent,  
					ModelData record, String property, String filter) {  
				// only match leaf nodes  
				if (record instanceof NonLeafTaxonomyModel) {  
					return false;  
				}  
				name = record.get(property);  
				if (property.equals("name"))
				{
					name = name.toLowerCase();  
					if (name.contains(filter.toLowerCase())) {  
						return true;  
					}
				}
				else if (property.equals("gid"))
				{
					name = name.toLowerCase();  
					if (name.startsWith(filter.toLowerCase())) {  
						return true;  
					}
				}
				return false;  
			}  
		};  
		filter.bind(tree.getStore()); 
		return filter;
	}
	public static String getProjectSettings(boolean withDelimiter)
	{
		StringBuffer buf = new StringBuffer();
		buf.append(qArea.getValue()+"@");
		buf.append(qType.getRawValue()+"@");
		buf.append(gType.getRawValue()+"@");
		buf.append(blastPrg.getRawValue()+"@");
		buf.append(expectancyBox.getRawValue()+"@");
		buf.append(filterBox.getRawValue()+"@");
		buf.append(txtField.getValue()+"@");
		buf.append(newProjectCheck.getValue()+"@");
		buf.append(blastDatabase.getValue().get("value")+"@");
		if (withDelimiter) buf.append(megaBlastCheck.isEnabled()+"------");
		else buf.append(megaBlastCheck.isEnabled());
		return buf.toString();
	}

	/**
	 * This method collects the form data and 
	 * organisms selected data, forms a delimited string and
	 * returns it. Delimiter used is ~.
	 * @return string containing form values and organism selected values
	 */
	public static String getData()
	{
		StringBuffer buf = new StringBuffer();
		String projectSettings = getProjectSettings(true);
		String selectedTaxes = getSelectedTaxes();
		if (selectedTaxes == null || projectSettings == null)
			return null;
		buf.append(projectSettings);
		buf.append(selectedTaxes);
		return buf.toString();
	}

	public static String getSelectedTaxes()
	{
		StringBuffer buf = new StringBuffer();
		List<ModelData> lst = tree.getCheckedSelection();
		if (lst.size() == 0) 
		{
			if (newProjectCheck.getValue().booleanValue()) 
			{
				Info.display("Error", "No taxes selected please select one");
				return null;
			}
			else
				return "";
		}
		if (newProjectCheck.getValue().booleanValue() && (txtField.getValue()== null || txtField.getValue().trim().equalsIgnoreCase("")))
		{
			Info.display("Error", "Please give your project a name");
			return null;
		}
		for (ModelData data : lst)
		{
			if (tree.isLeaf(data))
			{
				buf.append(data.get("name") + "~" + data.get("gid") + "@");
			}
		}
		return buf.substring(0,buf.length()-1);
	}

	private BlastGrid createGrid(String header)
	{
		int count = Random.nextInt();
		BlastGrid blastGrid = new BlastGrid(count);
		blastGrid.configureGrid();
		Portlet portlet = new Portlet();
		portlet.setData("mapKey", String.valueOf(count));
		configPanel(portlet);
		portlet.setLayout(new FitLayout());
		portlet.setTopComponent(blastGrid.createToolBar());
		portlet.add(blastGrid.getGrid());
		portlet.setHeight(MyBlast.clientHeight - 300);
		portlet.setIcon(((ExampleIcons) GWT.create(ExampleIcons.class)).table());
		portlet.setScrollMode(Scroll.AUTO);
		portlet.setHeading(header);
		portlet.setLayout(new FitLayout());
		portal.add(portlet, 1);
		map.put(blastGrid.getId(),blastGrid);
		return blastGrid;
	}

	public static void reselectOrg(List<BeanModel> lst)
	{
		if (lst.size() == 0)
		{
			Info.display("Error", "Nothing left in the grid to select");
			WidgetUtilities.hideLoading();
			return;
		}
		List<ModelData> checked = tree.getCheckedSelection();
		if (checked.size() > 0)
		{
			for (ModelData chk : checked)
			{
				tree.setChecked(chk, false);
			}
		}

		List<ModelData> list = tree.getStore().getAllItems();
		List<ModelData> tempList = new ArrayList<ModelData>();
		for (ModelData data : list)
		{
			String taxid = data.get("gid");
			if (taxid != null)
			{
				boolean found = false;
				for (BeanModel beanModel : lst)
				{
					String taxId = String.valueOf(beanModel.get("organismId"));
					if (taxId.equalsIgnoreCase(taxid))
					{
						tree.setChecked(data, true);
						found = true;
						break;
					}
				}
				if (!found )
				{
					tempList.add(data);
				}
			}
			else if (taxid == null && tree.isLeaf(data))
				tempList.add(data);
		}
		tree.setCheckStyle(TreePanel.CheckCascade.PARENTS);
		while (tempList.size() > 0)
		{
			List<ModelData> parentList = new ArrayList<ModelData>();
			for (ModelData data : tempList)
			{
				if (tree.getStore().getChildCount(data) == 0)
				{
					ModelData parent = tree.getStore().getParent(data);
					if (parent != null && !parentList.contains(parent)) 
						parentList.add(parent);
					tree.getStore().remove(data);	
				}
			}
			tempList = new ArrayList<ModelData>(parentList);
			parentList.clear();
		}
		tree.expandAll();
		Info.display("Info:", "checked new Ones");
	}

	/**
	 * This method makes a FormPanel, populated it
	 * and returns it.
	 * @return a FormPanel
	 */
	private FormPanel makeForm()
	{
		final FormPanel simple = new FormPanel();
		simple.setFrame(true);  
		simple.setWidth(350);
		qArea = new TextArea();
		qArea.setId("textArea");
		qArea.setFieldLabel("Query");
		qArea.setPreventScrollbars(false);
		qArea.setName("qArea");
		simple.add(qArea);
		Menu menu = new Menu();
		MenuItem menuItem = new MenuItem("Clear Query");
		menuItem.addListener(Events.Select, new SelectionListener<MenuEvent>() {
			@Override
			public void componentSelected(MenuEvent ce) {
				qArea.clear();
			}
		});
		menu.add(menuItem);
		qArea.setContextMenu(menu);
		final ListStore<FormModel> queryTypes = new ListStore<FormModel>();  
		final ListStore<FormModel> blastPrograms = new ListStore<FormModel>();
		final ListStore<FormModel> expectancy = new ListStore<FormModel>();
		final ListStore<FormModel> filter = new ListStore<FormModel>();
		final ListStore<FormModel> genomicType = new ListStore<FormModel>();
		final ListStore<FormModel> blastDatabasesStore = new ListStore<FormModel>();

		SelectionChangedListener<FormModel> selectionChangedListener = new SelectionChangedListener<FormModel>() {
			@Override
			public void selectionChanged(SelectionChangedEvent<FormModel> se) {
				if (se.getSelection().size() > 0)
				{
					FormModel queryFormModel = qType.getValue();
					FormModel databaseFormModel = gType.getValue();
					if (queryFormModel != null && databaseFormModel != null && blastPrograms.getModels().size() > 0)
					{
						String queryType = queryFormModel.get("name");
						String genomicType = databaseFormModel.get("name");
						if (queryType.equalsIgnoreCase("Protein") && genomicType.equalsIgnoreCase("Protein"))
						{
							blastPrg.setValue(blastPrograms.getAt(1));
							if (megaBlastCheck.isEnabled())
							{
								megaBlastCheck.setValue(false);
								megaBlastCheck.disable();
							}
						}
						else if (queryType.equalsIgnoreCase("DNA") && genomicType.equalsIgnoreCase("Genomic"))
						{
							blastPrg.setValue(blastPrograms.getAt(0));
							if (!megaBlastCheck.isEnabled()) megaBlastCheck.enable();
							megaBlastCheck.setValue(true);
						}
						else if (queryType.equalsIgnoreCase("DNA") && genomicType.equalsIgnoreCase("Protein"))
						{
							blastPrg.setValue(blastPrograms.getAt(2));
							if (megaBlastCheck.isEnabled())
							{
								megaBlastCheck.setValue(false);
								megaBlastCheck.disable();
							}
						}
						else if (queryType.equalsIgnoreCase("Protein") && genomicType.equalsIgnoreCase("Genomic"))
						{
							blastPrg.setValue(blastPrograms.getAt(3));
							if (megaBlastCheck.isEnabled())
							{
								megaBlastCheck.setValue(false);
								megaBlastCheck.disable();
							}
						}
					}
				}
			}
		};

		SelectionChangedListener<FormModel> selectionChangedListenerForBlastProgram = 
			new SelectionChangedListener<FormModel>() {

			@Override
			public void selectionChanged(SelectionChangedEvent<FormModel> se) {
				if (se.getSelection().size() > 0)
				{
					FormModel formModel = se.getSelectedItem();
					if (formModel == null) return;
					String blastProgramSelected = formModel.get("name");
					if (blastProgramSelected.equalsIgnoreCase("blastp"))
					{
						qType.setValue(queryTypes.getAt(1));
						gType.setValue(genomicType.getAt(1));
						if (megaBlastCheck.isEnabled())
						{
							megaBlastCheck.setValue(false);
							megaBlastCheck.disable();
						}
						blastDatabasesStore.removeAll();
						blastDatabasesStore.add(StaticData.getBlastPDatabase());
						blastDatabase.setValue(blastDatabasesStore.getAt(0));
					}
					else if (blastProgramSelected.equalsIgnoreCase("blastn"))
					{
						qType.setValue(queryTypes.getAt(0));
						gType.setValue(genomicType.getAt(0));
						if (!megaBlastCheck.isEnabled()) megaBlastCheck.enable();
						megaBlastCheck.setValue(true);
						blastDatabasesStore.removeAll();
						blastDatabasesStore.add(StaticData.getBlastNDatabase());
						blastDatabase.setValue(blastDatabasesStore.getAt(0));
					}
					else if (blastProgramSelected.equalsIgnoreCase("blastx"))
					{
						qType.setValue(queryTypes.getAt(0));
						gType.setValue(genomicType.getAt(1));
						if (megaBlastCheck.isEnabled())
						{
							megaBlastCheck.setValue(false);
							megaBlastCheck.disable();
						}
						blastDatabasesStore.removeAll();
						blastDatabasesStore.add(StaticData.getBlastXDatabase());
						blastDatabase.setValue(blastDatabasesStore.getAt(0));
					}
					else if (blastProgramSelected.equalsIgnoreCase("tblastn"))
					{
						qType.setValue(queryTypes.getAt(1));
						gType.setValue(genomicType.getAt(0));
						if (megaBlastCheck.isEnabled())
						{
							megaBlastCheck.setValue(false);
							megaBlastCheck.disable();
						}
						blastDatabasesStore.removeAll();
						blastDatabasesStore.add(StaticData.getTBlastNDatabase());
						blastDatabase.setValue(blastDatabasesStore.getAt(0));
					}
					else if (blastProgramSelected.equalsIgnoreCase("tblastx"))
					{
						qType.setValue(queryTypes.getAt(0));
						gType.setValue(genomicType.getAt(0));
						if (megaBlastCheck.isEnabled())
						{
							megaBlastCheck.setValue(false);
							megaBlastCheck.disable();
						}
						blastDatabasesStore.removeAll();
						blastDatabasesStore.add(StaticData.getTBlastXDatabase());
						blastDatabase.setValue(blastDatabasesStore.getAt(0));
					}
				}
			}};

			StoreListener<FormModel> storeListener = new StoreListener<FormModel>(){
				public void storeAdd(StoreEvent<FormModel> se)
				{
					if (se.getSource() == expectancyBox.getStore())
						expectancyBox.setValue(expectancy.getAt(3));
					else if (se.getSource() == blastPrg.getStore())
						blastPrg.setValue(blastPrograms.getAt(0));
					else if (se.getSource() == qType.getStore())
						qType.setValue(queryTypes.getAt(0));
					else if (se.getSource() == filterBox.getStore())
						filterBox.setValue(filter.getAt(0));
					else if (se.getSource() == gType.getStore())
						gType.setValue(genomicType.getAt(0));
				}
			};

			queryTypes.addStoreListener(storeListener);
			qType = new ComboBox<FormModel>();
			qType.addSelectionChangedListener(selectionChangedListener);
			qType.setFieldLabel("Query Seq.");
			qType.setName("name");
			qType.setDisplayField("name");
			qType.setValueField("name");
			qType.setStore(queryTypes);
			qType.setTypeAhead(true);  
			qType.setTriggerAction(TriggerAction.ALL);
			qType.setName("qType");
			simple.add(qType);


			genomicType.addStoreListener(storeListener);
			gType = new ComboBox<FormModel>();
			gType.addSelectionChangedListener(selectionChangedListener);
			gType.setFieldLabel("Database");
			gType.setName("name");
			gType.setValueField("name");
			gType.setDisplayField("name");
			gType.setStore(genomicType);
			gType.setTypeAhead(true);  
			gType.setTriggerAction(TriggerAction.ALL);
			gType.setName("gType");
			//			simple.add(gType);

			blastPrograms.addStoreListener(storeListener);
			blastPrg = new ComboBox<FormModel>();
			blastPrg.addSelectionChangedListener(selectionChangedListenerForBlastProgram);
			blastPrg.setFieldLabel("Blast-Prg");
			blastPrg.setName("name");
			blastPrg.setValueField("name");
			blastPrg.setDisplayField("name");
			blastPrg.setStore(blastPrograms);
			blastPrg.setTypeAhead(true);  
			blastPrg.setName("blastPrg");
			blastPrg.setTriggerAction(TriggerAction.ALL);
			simple.add(blastPrg);

			megaBlastCheck = new CheckBox();  
			megaBlastCheck.setBoxLabel("Megablast");  
			megaBlastCheck.setValue(true);
			megaBlastCheck.setHideLabel(true);
			megaBlastCheck.setName("megaBlastCheck");
			//		simple.add(megaBlastCheck);

			expectancy.addStoreListener(storeListener);
			expectancyBox = new ComboBox<FormModel>();
			expectancyBox.setFieldLabel("Expect");
			expectancyBox.setName("name");
			expectancyBox.setValueField("name");
			expectancyBox.setDisplayField("name");
			expectancyBox.setStore(expectancy);
			expectancyBox.setTypeAhead(true);  
			expectancyBox.setName("expectancyBox");
			expectancyBox.setTriggerAction(TriggerAction.ALL);
			simple.add(expectancyBox);


			filter.addStoreListener(storeListener);
			filterBox = new ComboBox<FormModel>();
			filterBox.setFieldLabel("Filter");
			filterBox.setName("name");
			filterBox.setValueField("name");
			filterBox.setDisplayField("name");
			filterBox.setStore(filter);
			filterBox.setTypeAhead(true);  
			filterBox.setTriggerAction(TriggerAction.ALL);
			filterBox.setName("filterBox");
			simple.add(filterBox);

			blastDatabase = new ComboBox<FormModel>();
			blastDatabase.setFieldLabel("Database");
			blastDatabase.setName("name");
			blastDatabase.setValueField("name");
			blastDatabase.setDisplayField("name");
			blastDatabase.setStore(blastDatabasesStore);
			blastDatabase.setTypeAhead(true);  
			blastDatabase.setTriggerAction(TriggerAction.ALL);
			blastDatabase.setName("blastData");
			simple.add(blastDatabase);

			txtField = new TextField<String>();
			txtField.setFieldLabel("Project");
			txtField.setAllowBlank(true);
			txtField.setName("txtField");
			txtField.setEmptyText("Enter the name of the project");
			simple.add(txtField);

			newProjectCheck = new CheckBox();  
			newProjectCheck.setBoxLabel("New Project");  
			newProjectCheck.setValue(true);
			newProjectCheck.setHideLabel(true);
			newProjectCheck.setName("newProjectCheck");
			//		simple.add(newProjectCheck);

			filter.add(StaticData.getFilterValues());
			expectancy.add(StaticData.getExpecValues());
			genomicType.add(StaticData.getDatabaseValues());
			queryTypes.add(StaticData.getQueryTypes());
			blastDatabasesStore.add(StaticData.getBlastNDatabase());
			// its important that blastPrograms will be loaded last
			blastPrograms.add(StaticData.getBlastProgams());

			ContentPanel contentPanel = new ContentPanel();
			HBoxLayout boxLayout = new HBoxLayout();
			boxLayout.setHBoxLayoutAlign(HBoxLayoutAlign.TOP);
			contentPanel.setLayout(boxLayout);

			contentPanel.add(megaBlastCheck);
			contentPanel.add(newProjectCheck);
			contentPanel.setHeaderVisible(false);
			simple.add(contentPanel);

			ContentPanel buttonPanel = new ContentPanel();
			buttonPanel.setLayout(new FitLayout());

			fetchButton = new Button("Fetch");
			fetchButton.addListener(Events.Select, this);

			buttonPanel.setButtonAlign(HorizontalAlignment.LEFT);
			buttonPanel.addButton(fetchButton);
			buttonPanel.setHeaderVisible(false);
			simple.add(buttonPanel);
			return simple;
	}

	private void preparePopUpPanel() {
		final PopupPanel popUpPanel = new PopupPanel(false, true);
		final Tracker tracker = utilities.new Tracker();
		final com.google.gwt.user.client.ui.FormPanel form = new com.google.gwt.user.client.ui.FormPanel();
		form.setEncoding(com.google.gwt.user.client.ui.FormPanel.ENCODING_MULTIPART);
		form.setMethod(com.google.gwt.user.client.ui.FormPanel.METHOD_POST);
		form.setWidth("450px");
		form.addSubmitCompleteHandler(new com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler()
		{
			@Override
			public void onSubmitComplete(SubmitCompleteEvent event) {
				popUpPanel.hide(true);
				tracker.setStatus(true);
				String result = event.getResults();
				if (result == null || result.contains("no"))
				{
					Info.display("Error","Cannot load the project");
				}
				else
				{
					Document document = XMLParser.parse(result);
					result = document.getDocumentElement().getFirstChild().getNodeValue();
					txtField.setValue(result);
					newProjectCheck.setValue(false);
					fetchButton.fireEvent(Events.Select);
				}
			}
		});


		form.setAction(GWT.getModuleBaseURL() + "fileServlet");
		ContentPanel main = new ContentPanel();
		main.setHeading("Upload Project File");

		VerticalPanel holder = new VerticalPanel();
		holder.setSpacing(10);
		holder.setHorizontalAlign(HorizontalAlignment.RIGHT);

		HorizontalPanel hp1 = new HorizontalPanel();//for browsing file
		hp1.setSpacing(10);

		HorizontalPanel hp2 = new HorizontalPanel();//for buttons
		hp2.setSpacing(10);

		FileUploadField file = new FileUploadField();
		file.setWidth(400);
		file.setName("fileUploadValue");
		file.setButtonOffset(10);
		file.setFieldLabel("File");
		file.setShim(true);
		hp1.add(file);

		Button btnSubmit = new Button("Submit");
		btnSubmit.addListener(Events.OnClick, new Listener<ButtonEvent>()
				{
			public void handleEvent(final ButtonEvent be)
			{
				form.submit();
				//Progress bar for upload
				final MessageBox box = MessageBox.wait("Progress", "Uploading File, please wait...", "Uploading...");
				final Timer t = new Timer()
				{
					public void run()
					{
						if (tracker.getStatus())
						{
							cancel();
							box.close();
						}
					}
				};
				t.scheduleRepeating(500);
			}
				});

		hp2.add(btnSubmit);
		Button btnCancel = new Button("Cancel");
		btnCancel.addListener(Events.OnClick, new Listener<ButtonEvent>()
				{
			public void handleEvent(final ButtonEvent be)
			{
				popUpPanel.hide(true);
			}
				});
		hp2.add(btnCancel);
		holder.add(hp1);
		holder.add(hp2);
		main.add(holder);
		form.add(main);

		popUpPanel.setWidget(form);
		popUpPanel.setPopupPositionAndShow(new PopupPanel.PositionCallback()
		{
			public void setPosition(int offsetWidth, int offsetHeight)
			{
				int left = (Window.getClientWidth() - offsetWidth) / 3;
				int top = (Window.getClientHeight() - offsetHeight) / 3;
				popUpPanel.setPopupPosition(left, top);
			}
		});
		popUpPanel.show();
	}

	public static void configPanel(final ContentPanel panel) {
		panel.setCollapsible(true);
		panel.setAnimCollapse(false);
		panel.getHeader().addTool(new ToolButton("x-tool-gear"));
		panel.getHeader().addTool(
				new ToolButton("x-tool-close", new SelectionListener<IconButtonEvent>() {

					@Override
					public void componentSelected(IconButtonEvent ce) {
						String key = panel.getData("mapKey");
						if (MyPortal.map.containsKey(key))
						{
							MyPortal.map.remove(key);
						}
						panel.removeFromParent();
					}
				}));
	}

	/* (non-Javadoc)
	 * @see com.extjs.gxt.ui.client.event.Listener#handleEvent(com.extjs.gxt.ui.client.event.BaseEvent)
	 */
	@Override
	public void handleEvent(ButtonEvent be) {

		final Tracker tracker = utilities.new Tracker();
		makePopUpPanel(tracker);
//		WidgetUtilities.displayLoading();
		final BlastGrid grid = createGrid("Loading..");
		AsyncCallback<List<BlastResult>> asyncCallback = new AsyncCallback<List<BlastResult>>() {

			@Override
			public void onSuccess(List<BlastResult> result) {
				BlastResult blastResult = result.get(0);
				String errorMessage = blastResult.getErrorMessage();
				if (result.size() == 1 && errorMessage != null)
				{
//					WidgetUtilities.hideLoading();
					tracker.setStatus(true);
					Info.display("Error", errorMessage);
					return;
				}

				BeanModelFactory beanFactory = BeanModelLookup.get().getFactory(BlastResult.class);
				BlastResult prjSettings = result.get(result.size() - 1);
				String projectSettings = prjSettings.getProjectSettings();
				Grid<BeanModel> tempGrid = grid.getGrid();
				if (projectSettings == null)
				{
					Portlet portlet = (Portlet)tempGrid.getParent();
					portlet.setHeading("Blast Results : " + txtField.getValue());
					tempGrid.getStore().add(beanFactory.createModel(result));
					projectUnsaved = true;
					grid.setGridProjectName(txtField.getValue());
				}
				else 
				{
					String[] params = projectSettings.split("@");
					Portlet portlet = (Portlet) tempGrid.getParent();
					portlet.setHeading("Blast Results : " + params[6]);
					result.remove(result.size() - 1);
					tempGrid.getStore().add(beanFactory.createModel(result));
					qArea.setValue(params[0]);
					setQueryType(params[1]); setGenomeType(params[2]); setProgramType(params[3]);
					setExpectancyValue(params[4]); setFilterBox(params[5]);
					blastDatabase.setValue(blastDatabase.getStore().getAt(0));
					txtField.setValue(params[6]);
					newProjectCheck.setValue(false);
					reselectOrg(tempGrid.getStore().getModels());
//					MenuItem item = (MenuItem) toolsMenu.getItemByItemId("reselectMenuItem");
//					item.fireEvent(Events.Select, new MenuEvent(toolsMenu));
					projectUnsaved = false;
					grid.setGridProjectName(params[6]);
				}
				map.put(grid.getId(), grid);
//				WidgetUtilities.hideLoading();
				tracker.setStatus(true);
			}

			@Override
			public void onFailure(Throwable caught) {
//				WidgetUtilities.hideLoading();
				tracker.setStatus(true);
				Info.display("Error", "Could not process request");
			}

			private void setQueryType(String param) 
			{
				if (param.equals("DNA")) qType.setValue(qType.getStore().getAt(0));
				else if (param.equals("Protein")) qType.setValue(qType.getStore().getAt(1));
			}

			private void setFilterBox(String param) 
			{
				if (param.equals("none")) filterBox.setValue(filterBox.getStore().getAt(0));

			}

			private void setExpectancyValue(String param) 
			{
				if (param.equals("0.0001")) expectancyBox.setValue(expectancyBox.getStore().getAt(0));
				else if (param.equals("0.01")) expectancyBox.setValue(expectancyBox.getStore().getAt(1));
				else if (param.equals("1")) expectancyBox.setValue(expectancyBox.getStore().getAt(2));
				else if (param.equals("10")) expectancyBox.setValue(expectancyBox.getStore().getAt(3));
				else if (param.equals("100")) expectancyBox.setValue(expectancyBox.getStore().getAt(4));
				else if (param.equals("1000")) expectancyBox.setValue(expectancyBox.getStore().getAt(5));
			}

			private void setProgramType(String param) 
			{
				if (param.equals("blastn")) blastPrg.setValue(blastPrg.getStore().getAt(0));
				else if (param.equals("blastp")) blastPrg.setValue(blastPrg.getStore().getAt(1));
				else if (param.equals("blastx")) blastPrg.setValue(blastPrg.getStore().getAt(2));
				else if (param.equals("tblastn")) blastPrg.setValue(blastPrg.getStore().getAt(3));
				else if (param.equals("tblastx")) blastPrg.setValue(blastPrg.getStore().getAt(4));
			}

			private void setGenomeType(String param) 
			{
				if (param.equals("Genomic")) gType.setValue(gType.getStore().getAt(0));
				else if (param.equals("Protein")) gType.setValue(gType.getStore().getAt(1));
			}

		};
		String data = getData();
		if (data != null)
		{
			MyBlast.blastServiceInterfaceAsync.getResults(getData(), asyncCallback);
		}
		else
		{
			WidgetUtilities.hideLoading();
		}
	}
	private void makePopUpPanel(final Tracker tracker) {
		final Listener<MessageBoxEvent> l = new Listener<MessageBoxEvent>() {  
		      public void handleEvent(MessageBoxEvent ce) {  
		        Button btn = ce.getButtonClicked();
		        if (btn != null && btn.getText().equalsIgnoreCase("Cancel"))
		        {
		        	AsyncCallback<Boolean> asyncCallback = new AsyncCallback<Boolean>() {
						
						@Override
						public void onSuccess(Boolean result) 
						{
//							tracker.setStatus(true);
							Info.display("Status", "Stopping signal send successfully");
						}
						
						@Override
						public void onFailure(Throwable caught) 
						{
							Info.display("Status", "Cannot stop calculation");
						}
					};
					MyBlast.blastServiceInterfaceAsync.stopRunning(MyPortal.txtField.getValue(), asyncCallback);
			      } 
		        }
		    };
		
		final MessageBox box = new MessageBox();
	    box.setTitle("Progress");
	    box.setMessage("Running Blast, please wait...");
	    box.setType(MessageBoxType.WAIT);
	    box.setProgressText("Calculating...");
	    box.setButtons(MessageBox.CANCEL);
	    box.setClosable(false);
	    box.addCallback(l);
	    box.show();
        Timer t = new Timer() 
        {  
          @Override  
          public void run() {  
            if (tracker.status)
            {
            	cancel();
            	box.close(); 
            }
          }  
        };  
        t.scheduleRepeating(5000);  
	}
} // MyPortal
